package com.yida.gwj.basis.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.yida.common.core.constant.SecurityConstants;
import com.yida.common.core.exception.ServiceException;
import com.yida.common.core.text.Convert;
import com.yida.common.core.utils.DateUtils;
import com.yida.common.core.utils.StringUtils;
import com.yida.common.security.utils.SecurityUtils;
import com.yida.gwj.api.domain.GwjConfStep;
import com.yida.gwj.api.service.RemoteGwjConfigService;
import com.yida.gwj.basis.domain.*;
import com.yida.gwj.basis.domain.dto.GwjInitApiBuildDTO;
import com.yida.gwj.basis.domain.dto.GwjInitApiHouseDTO;
import com.yida.gwj.basis.domain.dto.GwjInitApiOwnerDTO;
import com.yida.gwj.basis.domain.request.GwjInitApiRequest;
import com.yida.gwj.basis.domain.request.GwjInitBusinessSaveSubmitRequest;
import com.yida.gwj.basis.enums.GwjInitBusinessBuildStatus;
import com.yida.gwj.basis.service.*;
import com.yida.gwj.common.constant.GwjConstants;
import com.yida.gwj.common.domain.*;
import com.yida.gwj.common.domain.request.GwjBaseBuildRequest;
import com.yida.gwj.common.enums.GwjBusinessFlagType;
import com.yida.gwj.common.enums.GwjBusinessHouseStatus;
import com.yida.gwj.common.enums.GwjBusinessStatus;
import com.yida.gwj.common.enums.StepConfigInfoEnum;
import com.yida.gwj.common.service.IGwjBaseBuildService;
import com.yida.gwj.common.service.IGwjBaseBusinessNumService;
import com.yida.gwj.common.service.IGwjBaseHouseService;
import com.yida.gwj.common.service.IGwjBaseOwnerService;
import com.yida.gwj.common.utils.GwjConvertUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 小区客体数据更新（基础数据管理模块）Service业务层处理
 *
 * @author lqq
 * @date 2022-11-15
 */
@Service
public class GwjInitUpdateBuildBusinessServiceImpl implements IGwjInitUpdateBuildBusinessService {

    @Resource
    private IGwjInitBusinessLogService logService;

    @Resource
    private IGwjBaseBusinessNumService businessNumService;

    @Resource
    private IGwjInitBusinessService businessService;

    @Resource
    private IGwjInitBusinessCommunityService businessCommunityService;

    @Resource
    private IGwjInitBusinessBuildService businessBuildService;

    @Resource
    private IGwjInitBusinessHouseService businessHouseService;

    @Resource
    private IGwjInitBusinessOwnerService businessOwnerService;

    @Resource
    private IGwjInitApiService apiService;

    @Resource
    private IGwjBaseBuildService buildService;

    @Resource
    private IGwjBaseHouseService houseService;

    @Resource
    private IGwjBaseOwnerService ownerService;

    @Resource
    private RemoteGwjConfigService remoteGwjConfigService;

    /**
     * 小区客体数据更新（保存）
     *
     * @param saveSubmitRequest 请求参数
     * @return /
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long saveBusiness(GwjInitBusinessSaveSubmitRequest saveSubmitRequest) {
        GwjInitBusiness business = saveSubmitRequest.getBusiness();
        GwjInitBusinessCommunity community = saveSubmitRequest.getBusinessCommunity();
        List<GwjInitBusinessBuild> builds = saveSubmitRequest.getBusinessBuilds();
        //处理业务信息
        //业务流程
        business.setFlowId(remoteGwjConfigService.selectGwjConfBusinessFlagByBizFlagId(business.getBizFlagId(), SecurityConstants.INNER).getData().getFlowId());
        //地区
        business.setAreaId(community.getAreaId());
        //TODO 获取业务编号加锁
        GwjBaseBusinessNum businessNum = businessNumService.getNextNum(business.getAreaId(), business.getBizFlagId());
        //业务编号
        business.setBizNum(Convert.toLong(businessNum.toString()));
        //业务名称
        if (StringUtils.isBlank(business.getBizName())) {
            business.setBizName(community.getCommunityName());
        }
        businessService.insert(business);
        //处理业务小区信息
        community.setBizId(business.getBizId());
        //保存小区信息
        businessCommunityService.save(community);
        //保存其他业务数据
        saveDataByStatus(builds, community);
        //日志
        logService.addSaveLog(business);
        return business.getBizId();
    }

    /**
     * 楼栋更新（选择楼栋）
     *
     * @param buildRequest 请求参数
     * @return /
     */
    @Override
    public List<GwjInitBusinessBuild> updateBuild(GwjBaseBuildRequest buildRequest) {
        if (StringUtils.isEmpty(buildRequest.getBuildIds())) {
            throw new ServiceException("请选择楼栋");
        }
        //查询所选楼栋的楼栋标识码
        List<GwjBaseBuild> builds = buildService.selectGwjBaseBuildListByBuildIds(buildRequest.getBuildIds());
        if (StringUtils.isEmpty(builds)) {
            throw new ServiceException("查无数据");
        }
        //返回参数
        List<GwjInitBusinessBuild> businessBuilds = new ArrayList<GwjInitBusinessBuild>();
        //佣接口更新数据
        GwjInitApiRequest apiRequest = new GwjInitApiRequest();
        apiRequest.setAreaId(buildRequest.getAreaId());
        builds.forEach(baseBuild -> {
            apiRequest.setBuildCode(baseBuild.getBuildCode());
            List<GwjInitApiBuildDTO> result = apiService.getBuild(apiRequest);
            GwjInitBusinessBuild businessBuild = GwjConvertUtil.convert(result.get(0), GwjInitBusinessBuild.class);
            businessBuild.setBuildId(baseBuild.getBuildId());
            businessBuild.setBuildName(baseBuild.getBuildName());
            businessBuilds.add(businessBuild);
        });
        return businessBuilds;
    }

    /**
     * 通过楼栋的状态保存
     *
     * @param builds    /
     * @param community /
     */
    public void saveDataByStatus(List<GwjInitBusinessBuild> builds, GwjInitBusinessCommunity community) {
        //删除
        List<GwjInitBusinessBuild> del = builds.stream().filter(build -> build.getStatus().equals(GwjInitBusinessBuildStatus.DEL.getCode())).collect(Collectors.toList());
        if (StringUtils.isNotEmpty(del)) {
            businessBuildService.deleteByList(del, community.getBizId());
        }
        //保存修改
        List<GwjInitBusinessBuild> update = builds.stream().filter(build -> build.getStatus().equals(GwjInitBusinessBuildStatus.UPDATE.getCode())).collect(Collectors.toList());
        if (StringUtils.isNotEmpty(update)) {
            update.forEach(b -> {
                b.setAreaId(community.getAreaId());
                b.setStreetId(community.getStreetId());
                b.setUpdateBy(SecurityUtils.getLoginUser().getSysUser().getRealName());
                b.setUpdateTime(DateUtils.getNowDate());
            });
            businessBuildService.updateBatch(update);
        }
        //新增
        List<GwjInitBusinessBuild> add = builds.stream().filter(build -> build.getStatus().equals(GwjInitBusinessBuildStatus.ADD.getCode())).collect(Collectors.toList());
        if (StringUtils.isEmpty(update) && StringUtils.isEmpty(add)) {
            throw new ServiceException("请选择楼栋");
        }
        if (StringUtils.isNotEmpty(add)) {
            add.forEach(build -> {
                build.setBizId(community.getBizId());
                build.setAreaId(community.getAreaId());
                build.setStreetId(community.getStreetId());
                build.setBizCommunityId(community.getBizCommunityId());
                //保存业务楼栋信息
                businessBuildService.save(build);
                //保存业务房屋信息
                GwjInitApiRequest apiRequest = new GwjInitApiRequest();
                apiRequest.setAreaId(community.getAreaId());
                apiRequest.setBuildCode(build.getBuildCode());
                List<GwjInitApiHouseDTO> apiHouseData = apiService.getHouse(apiRequest);
                //房屋不为空
                if (StringUtils.isNotEmpty(apiHouseData)) {
                    List<GwjInitBusinessHouse> businessHouses = GwjConvertUtil.convertList(apiHouseData, GwjInitBusinessHouse.class);
                    for (GwjInitBusinessHouse businessHouse : businessHouses) {
                        businessHouse.setBizId(community.getBizId());
                        businessHouse.setAreaId(community.getAreaId());
                        businessHouse.setStreetId(community.getStreetId());
                        businessHouse.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getRealName());
                        businessHouse.setCreateTime(DateUtils.getNowDate());
                    }
                    businessHouses = businessHouses.stream().map(item -> {
                        if (ObjectUtil.isEmpty(item.getForecastSize())) {
                            item.setForecastSize(BigDecimal.ZERO);
                        }
                        if (ObjectUtil.isEmpty(item.getActualSize())) {
                            item.setActualSize(BigDecimal.ZERO);
                        }
                        return item;
                    }).collect(Collectors.toList());
                    //保存房屋数据
                    businessHouseService.saveBatch(businessHouses);
                    //分段拉取业主信息
                    List<String> houseCodes = businessHouses.stream().map(GwjBaseBusinessHouse::getHouseCode).collect(Collectors.toList());
                    List<List<String>> codeList = GwjConvertUtil.partition(houseCodes, 10);
                    for (List<String> list : codeList) {
                        String houseCodeStr = StringUtils.join(list, ",");
                        //保存业务业主信息
                        GwjInitApiRequest apiRequest2 = new GwjInitApiRequest();
                        apiRequest2.setAreaId(community.getAreaId());
                        apiRequest2.setHouseCode(houseCodeStr);
                        List<GwjInitApiOwnerDTO> apiOwnerData = apiService.getOwner(apiRequest2);
                        //业主不为空
                        if (StringUtils.isNotEmpty(apiOwnerData)) {
                            List<GwjInitBusinessOwner> businessOwners = GwjConvertUtil.convertList(apiOwnerData, GwjInitBusinessOwner.class);
                            businessOwners.forEach(owner -> {
                                owner.setBizId(community.getBizId());
                                owner.setAreaId(community.getAreaId());
                                owner.setStreetId(community.getStreetId());
                                owner.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getRealName());
                                owner.setCreateTime(DateUtils.getNowDate());
                            });
                            businessOwnerService.saveBatch(businessOwners);
                        }
                    }
                }
            });
        }
    }


    /**
     * 小区客体数据更新（保存修改）
     *
     * @param saveSubmitRequest 请求参数
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateBusiness(GwjInitBusinessSaveSubmitRequest saveSubmitRequest) {
        GwjInitBusiness business = saveSubmitRequest.getBusiness();
        GwjInitBusinessCommunity community = saveSubmitRequest.getBusinessCommunity();
        List<GwjInitBusinessBuild> businessBuilds = saveSubmitRequest.getBusinessBuilds();
        //检验当前登录账号是否有权限
        businessService.checkPermission(business.getBizId());
        business.setStatus(GwjBusinessStatus.NORMAL.getCode());
        businessService.updateById(business);
        //保存业务小区信息
        community.setBizId(business.getBizId());
        if (StringUtils.isNull(community.getBizCommunityId())) {
            businessCommunityService.save(community);
        } else {
            businessCommunityService.updateById(community);
        }
        //保存楼栋等信息
        saveDataByStatus(businessBuilds, community);
        //日志
        logService.addSaveLog(business);
    }

    /**
     * 小区客体数据更新（提交）
     *
     * @param saveSubmitRequest 请求参数
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void submitBusiness(GwjInitBusinessSaveSubmitRequest saveSubmitRequest) {
        GwjInitBusiness business = saveSubmitRequest.getBusiness();
        GwjInitBusinessLog businessLog = saveSubmitRequest.getBusinessLog();
        GwjInitBusinessCommunity community = saveSubmitRequest.getBusinessCommunity();
        List<GwjInitBusinessBuild> builds = saveSubmitRequest.getBusinessBuilds();
        if (StringUtils.isNull(business.getBizId())) {
            throw new ServiceException("请先保存业务");
        }
        //判断是否已有数据 可以直接提交
        if (StringUtils.isNull(businessCommunityService.getOne(business.getBizId())) && StringUtils.isNull(community)) {
            throw new ServiceException("小区信息不能为空");
        }
        if (StringUtils.isEmpty(businessBuildService.getListByBizId(business.getBizId())) && StringUtils.isEmpty(builds)) {
            throw new ServiceException("小区楼栋不能为空");
        }
        //检验当前登录账号是否有权限
        businessService.checkPermission(business.getBizId());
        //设置日志流程步骤,业务编号
        businessLog.setStepId(business.getStepId());
        businessLog.setBizId(business.getBizId());
        //获取当前步骤所有配置
        List<String> configInfos = remoteGwjConfigService.selectGwjConfStepConfigInfoCodeListByBizFlagId(businessLog.getStepId(), SecurityConstants.INNER).getData();
        //判断是否需要选收件人
        if (StringUtils.containsAny(configInfos, StepConfigInfoEnum.SUBMIT_CHOOSE_USER.getCode()) && StringUtils.isAnyBlank(Convert.toStr(businessLog.getUserId()), businessLog.getRealName())) {
            throw new ServiceException("请选择下一位收件人");
        }
        //当前办理人员
        business.setCurrentOperId(StringUtils.isNull(businessLog.getUserId()) ? SecurityUtils.getUserId() : businessLog.getUserId());
        business.setCurrentOperName(StringUtils.isBlank(businessLog.getRealName()) ? SecurityUtils.getLoginUser().getSysUser().getRealName() : businessLog.getRealName());
        //当前步骤
        GwjConfStep nextStep = remoteGwjConfigService.selectNextGwjConfStepByFlagId(GwjBusinessFlagType.UPDATE_BUILD.getCode(), business.getStepId(), SecurityConstants.INNER).getData();
        business.setStepId(nextStep.getStepId());
        //更新业务
        business.setStatus(GwjBusinessStatus.NORMAL.getCode());
        businessService.updateById(business);
        //判断当前流程是否可以编辑
        if (StringUtils.containsAny(configInfos, StepConfigInfoEnum.SUBMIT_EDIT.getCode())) {
            if (StringUtils.isNotNull(community) && StringUtils.isNotEmpty(builds)) {
                //保存业务小区、楼栋、房屋、业主等信息
                community.setBizId(business.getBizId());
                if (StringUtils.isNull(community.getBizCommunityId())) {
                    businessCommunityService.save(community);
                } else {
                    businessCommunityService.updateById(community);
                }
                saveDataByStatus(builds, community);
            }
        }
        //日志
        logService.addSubmitLog(business, businessLog);
        //判断是不是已经最后一步
        if (StringUtils.isNull(remoteGwjConfigService.selectNextGwjConfStepByFlagId(GwjBusinessFlagType.UPDATE_BUILD.getCode(), nextStep.getStepId(), SecurityConstants.INNER).getData())) {
            //将业务数据插入基础数据
            //小区数据
            GwjInitBusinessCommunity businessCommunity = businessCommunityService.getOne(business.getBizId());
            //楼栋数据
            List<GwjInitBusinessBuild> businessBuilds = businessBuildService.getListByBizId(business.getBizId());
            if (StringUtils.isNotEmpty(businessBuilds)) {
                List<GwjBaseBuild> baseBuilds = GwjConvertUtil.convertList(businessBuilds, GwjBaseBuild.class);
                baseBuilds.forEach(build -> {
                    build.setCommunityId(businessCommunity.getCommunityId());
                    build.setTotalLayer(ObjectUtil.isNull(build.getTotalLayer()) ? 0 : build.getTotalLayer());
                    build.setPublicFlag(GwjConstants.NO);
                    build.setUpdateBy(SecurityUtils.getLoginUser().getSysUser().getRealName());
                    build.setUpdateTime(DateUtils.getNowDate());
                });
                buildService.updateBatchGwjBaseBuild(baseBuilds);
                //房屋数据
                String[] buildCodes = businessBuilds.stream().map(GwjBaseBusinessBuild::getBuildCode).toArray(String[]::new);
                List<GwjInitBusinessHouse> businessHouses = businessHouseService.getList(GwjBusinessHouseStatus.CONFIRM.getCode(), business.getBizId());
                if (StringUtils.isNotEmpty(businessHouses)) {
                    List<GwjBaseHouse> newHouses = GwjConvertUtil.convertList(businessHouses, GwjBaseHouse.class);
                    //查询原来房屋
                    List<GwjBaseHouse> oldHouses = houseService.selectGwjBaseListByBuildCodesAndAreaId(buildCodes, businessCommunity.getAreaId());
                    //判断做更新还是新增
                    if (StringUtils.isNotEmpty(oldHouses)) {
                        newHouses.forEach(newHouse -> oldHouses.forEach(oldHouse -> {
                            if (oldHouse.getHouseCode().equals(newHouse.getHouseCode())) {
                                newHouse.setHouseId(oldHouse.getHouseId());
                            }
                        }));
                    }
                    newHouses.forEach(house -> {
                        if (StringUtils.isNotNull(house.getHouseId())) {
                            houseService.updateGwjBaseHouse(house);
                        } else {
                            house.setPublicFlag(GwjConstants.NO);
                            house.setDepositMoney(BigDecimal.ZERO);
                            house.setDepositSize(BigDecimal.ZERO);
                            house.setAddedMoney(BigDecimal.ZERO);
                            house.setUsedMoney(BigDecimal.ZERO);
                            house.setBlockedMoney(BigDecimal.ZERO);
                            house.setInterestMoney(BigDecimal.ZERO);
                            house.setCurrentMoney(BigDecimal.ZERO);
                            house.setUpdateBy("");
                            house.setUpdateTime(null);
                            houseService.insertGwjBaseHouse(house);
                        }
                    });
                    //业主数据
                    String[] houseCodes = businessHouses.stream().map(GwjBaseBusinessHouse::getHouseCode).toArray(String[]::new);
                    List<GwjInitBusinessOwner> businessOwners = businessOwnerService.getList(houseCodes, business.getBizId());
                    if (StringUtils.isNotEmpty(businessOwners)) {
                        //查询原来业主
                        List<GwjBaseOwner> oldOwners = ownerService.selectGwjBaseListByGwjBaseHouseCodes(houseCodes, businessCommunity.getAreaId());
                        List<GwjBaseOwner> newOwners = GwjConvertUtil.convertList(businessOwners, GwjBaseOwner.class);
                        //判断做更新还是新增
                        if (StringUtils.isNotEmpty(oldOwners)) {
                            newOwners.forEach(newOwner -> oldOwners.forEach(oldOwner -> {
                                if (newOwner.getHouseCode().equals(oldOwner.getHouseCode())) {
                                    newOwner.setOwnerId(oldOwner.getOwnerId());
                                }
                            }));
                        }
                        newOwners.forEach(owner -> {
                            if (StringUtils.isNotNull(owner.getOwnerId())) {
                                ownerService.updateGwjBaseOwner(owner);
                            } else {
                                ownerService.insertGwjBaseOwner(owner);
                            }
                        });
                    }
                }
            }
            //业务更新为完结
            business.setStatus(GwjBusinessStatus.FINISH.getCode());
            businessService.updateById(business);
            //日志
            logService.addFinishLog(business);
        }
    }
}
